<?php

/**
 * CCoreLabsWebMail
 *
 * @author Usenko Timur <usenko.timur@gmail.com>
 * @package labs
 */

CCore::Using('labs.webmail.constants');
CCore::Using('labs.webmail.account');

/**
 * @package labs
 */
class CCoreLabsWebMail
{
	const OBJECT_ERROR_CODE = 1000;

	/**
	 * @var array
	 */
	private $_aExceptionErrors = array(
		0 => 'Неизвестный exception',
		1 => 'Не правильный тип входящего почтового протокола',
		2 => 'Не правильный тип исходящего почтового протокола',
	);

	/**
	 * @var CCoreLabsWebMailAccount
	 */
	private $_oWebMailAccount;

	/**
	 * @var CCoreLabsWebMailProtocolsIncImap
	 */
	private $_oIncStorage;

	/**
	 * @var CCoreLabsWebMailAccount
	 */
	//private $_oOutStorage;

	/**
	 * @return CCoreLabsWebMail
	 *
	 * @throw CCoreWebMailException
	 */
	public function __construct(CCoreLabsWebMailAccount $oWebMailAccount)
	{
		$this->_oWebMailAccount = $oWebMailAccount;
		
		switch ($oWebMailAccount->IncProtocol())
		{
			case C_WEBMAIL_INC_MAIL_PROTOCOL_POP3:
				CCore::Using('labs.webmail.protocols.inc.pop3');
				$this->_oIncStorage = new CCoreLabsWebMailProtocolsIncPop3($oWebMailAccount);
				break;
			case C_WEBMAIL_INC_MAIL_PROTOCOL_IMAP:
				CCore::Using('labs.webmail.protocols.inc.imap');
				$this->_oIncStorage = new CCoreLabsWebMailProtocolsIncImap($oWebMailAccount);
				break;
			default:
				$this->_throwException('CCoreWebMailException', 1);
				break;
		}
		
//		switch ($oWebMailAccount->OutProtocol())
//		{
//			case C_WEBMAIL_OUT_MAIL_PROTOCOL_SMTP:
//				CCore::Using('labs.webmail.protocols.out.smtp');
//				$this->_oOutStorage = new CCoreLabsWebMailProtocolsOutSmtp($oWebMailAccount);
//				break;
//			default:
//				$this->_throwException('CCoreWebMailException', 2);
//				break;
//		}
	}

	/**
	 * @return bool
	 */
	public function TestIncConnection()
	{
		return $this->_oIncStorage->TestIncConnection();
	}
	
	/**
	 * @return bool
	 */
	public function ForceCloseConnection()
	{
		return $this->_oIncStorage->ForceCloseConnection();
	}

	/**
	 * @return CCoreLabsWebMailFolderCollection
	 *
	 * @throw CCoreWebMailException
	 */
	public function Folders()
	{
		try
		{
			return $this->_oIncStorage->Folders();
		}
		catch (CCoreWebMailProtocolsIncException $oException)
		{
			$this->_throwParentException('CCoreWebMailException', $oException);
		}
	}

	/**
	 * @param string $sFolderParentFullName
	 * @param string $sFolderNameInUtf8
	 *
	 * @return bool
	 *
	 * @throw CCoreWebMailException
	 */
	public function FolderCreate($sFolderParentFullName, $sFolderNameInUtf8)
	{
		try
		{
			return $this->_oIncStorage->FolderCreate($sFolderParentFullName, $sFolderNameInUtf8);
		}
		catch (CCoreWebMailProtocolsIncException $oException)
		{
			$this->_throwParentException('CCoreWebMailException', $oException);
		}
	}

	/**
	 * @param string $sFolderFullName
	 *
	 * @return bool
	 *
	 * @throw CCoreWebMailException
	 */
	public function FolderDelete($sFolderFullName)
	{
		try
		{
			return $this->_oIncStorage->FolderDelete($sFolderFullName);
		}
		catch (CCoreWebMailProtocolsIncException $oException)
		{
			$this->_throwParentException('CCoreWebMailException', $oException);
		}
	}

	/**
	 * @param string $sFolderFullName
	 * @param string $sNewNameInUtf8
	 *
	 * @return bool
	 *
	 * @throw CCoreWebMailException
	 */
	public function FolderRename($sFolderFullName, $sNewNameInUtf8)
	{
		try
		{
			return $this->_oIncStorage->FolderRename($sFolderFullName, $sNewNameInUtf8);
		}
		catch (CCoreWebMailProtocolsIncException $oException)
		{
			$this->_throwParentException('CCoreWebMailException', $oException);
		}
	}

	/**
	 * @param string $sFolderFullName
	 * @param array $aUids
	 * @param bool $bIsSet
	 * @return bool
	 *
	 * @throw CCoreWebMailException
	 */
	public function SetFlagged($sFolderFullName, $aUids, $bIsSet)
	{
		try
		{
			return $this->_oIncStorage->SetFlagged($sFolderFullName, $aUids, $bIsSet);
		}
		catch (CCoreWebMailProtocolsIncException $oException)
		{
			$this->_throwParentException('CCoreWebMailException', $oException);
		}
	}

	/**
	 * @param string $sFolderFullName
	 * @param array $aUids
	 * @param bool $bIsSet
	 * @return bool
	 *
	 * @throw CCoreWebMailException
	 */
	public function SetSeen($sFolderFullName, $aUids, $bIsSet)
	{
		try
		{
			return $this->_oIncStorage->SetSeen($sFolderFullName, $aUids, $bIsSet);
		}
		catch (CCoreWebMailProtocolsIncException $oException)
		{
			$this->_throwParentException('CCoreWebMailException', $oException);
		}
	}

	/**
	 * @param string $sFolderFullName
	 * @param array $aUids
	 *
	 * @return CCoreLabsWebMailHeaderCollection
	 *
	 * @throw CCoreWebMailException
	 */
	public function MessageHeaders($sFolderFullName, $aUids)
	{
		try
		{
			return $this->_oIncStorage->MessageHeaders($sFolderFullName, $aUids);
		}
		catch (CCoreWebMailProtocolsIncException $oException)
		{
			$this->_throwParentException('CCoreWebMailException', $oException);
		}
	}

	/**
	 * @param string $sFolderFullName
	 * @param string $sUid
	 * @return string
	 *
	 * @throw CCoreWebMailException
	 */
	public function MessageFullHeaders($sFolderFullName, $sUid)
	{
		try
		{
			return $this->_oIncStorage->MessageFullHeaders($sFolderFullName, $sUid);
		}
		catch (CCoreWebMailProtocolsIncException $oException)
		{
			$this->_throwParentException('CCoreWebMailException', $oException);
		}
	}

	/**
	 * @param string $sFolderFullName
	 * @param string $sUid
	 *
	 * @throw CCoreWebMailException
	 */
	public function MessageFullBodyThroughCallback($sFolderFullName, $sUid, $mFormationCallback)
	{
		try
		{
			return $this->_oIncStorage->MessageFullBodyThroughCallback($sFolderFullName, $sUid, $mFormationCallback);
		}
		catch (CCoreWebMailProtocolsIncException $oException)
		{
			$this->_throwParentException('CCoreWebMailException', $oException);
		}
	}

	/**
	 * @param string $sFolderFullName
	 * @return string
	 *
	 * @throw CCoreWebMailException
	 */
	public function FolderHash($sFolderFullName)
	{
		try
		{
			return $this->_oIncStorage->FolderHash($sFolderFullName);
		}
		catch (CCoreWebMailProtocolsIncException $oException)
		{
			$this->_throwParentException('CCoreWebMailException', $oException);
		}
	}

	/**
	 * @param string $sHash
	 * @param string $sFolderFullName
	 * @param string $sSearchDesc = ''
	 *
	 * @return array
	 *
	 * @throw CCoreWebMailException
	 */
	public function FolderHashUids($sHash, $sFolderFullName, $sSearchDesc = '')
	{
		try
		{
			return $this->_oIncStorage->FolderHashUids($sHash, $sFolderFullName, $sSearchDesc);
		}
		catch (CCoreWebMailProtocolsIncException $oException)
		{
			$this->_throwParentException('CCoreWebMailException', $oException);
		}
	}

	/**
	 * @param string $sFolderFullName
	 * @param array $aUids
	 *
	 * @throw CCoreWebMailException
	 */
	public function MessagesThroughCallback($sFolderFullName, $aUids, $mFormationCallback)
	{
		try
		{
			$this->_oIncStorage->MessagesThroughCallback($sFolderFullName, $aUids, $mFormationCallback);
		}
		catch (CCoreWebMailProtocolsIncException $oException)
		{
			$this->_throwParentException('CCoreWebMailException', $oException);
		}
	}

	/**
	 * @param string $sFolderFullName
	 * @param string $sUid
	 * @param string $sMimeIndex
	 * @param mixed $mFormationCallback
	 *
	 * @throw CCoreWebMailException
	 */
	public function AttachmentThroughCallback($sFolderFullName, $sUid, $sMimeIndex, $mFormationCallback)
	{
		try
		{
			$this->_oIncStorage->AttachmentThroughCallback($sFolderFullName, $sUid, $sMimeIndex, $mFormationCallback);
		}
		catch (CCoreWebMailProtocolsIncException $oException)
		{
			$this->_throwParentException('CCoreWebMailException', $oException);
		}
	}

	/**
	 * @param string $sFolderFullName
	 * @param string $sFileName
	 *
	 * @throw CCoreWebMailException
	 */
	public function AppendMailFromFile($sFolderFullName, $sFileName)
	{
		try
		{
			return $this->_oIncStorage->AppendMailFromFile($sFolderFullName, $sFileName);
		}
		catch (CCoreWebMailProtocolsIncException $oException)
		{
			$this->_throwParentException('CCoreWebMailException', $oException);
		}
	}

	/**
	 * @param string $sExceptionName
	 * @param int $iCode
	 * @return int
	 */
	private function _throwException($sExceptionName, $iCode)
	{
		if (!isset($this->_aExceptionErrors[$iCode]))
		{
			$iCode = 0;
		}

		throw new $sExceptionName($this->_aExceptionErrors[$iCode], $this->_getErrorCode(self::OBJECT_ERROR_CODE + $iCode));
	}

	/**
	 * @param string $sExceptionName
	 * @param Exception $oException
	 * @return int
	 */
	private function _throwParentException($sExceptionName, $oException)
	{
		throw new $sExceptionName($oException->getMessage(), $oException->getCode(), $oException);
	}
}
